{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Managing the database"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    ".. seealso::\n",
    "\n",
    "    :doc:`/command_line_tools/nbgrader-db-student-add`\n",
    "        Command line options for ``nbgrader db student add``\n",
    "\n",
    "    :doc:`/command_line_tools/nbgrader-db-student-import`\n",
    "        Command line options for ``nbgrader db student import``\n",
    "\n",
    "    :doc:`/command_line_tools/nbgrader-db-student-remove`\n",
    "        Command line options for ``nbgrader db student remove``\n",
    "\n",
    "    :doc:`/command_line_tools/nbgrader-db-student-list`\n",
    "        Command line options for ``nbgrader db student list``\n",
    "\n",
    "    :doc:`/command_line_tools/nbgrader-db-assignment-add`\n",
    "        Command line options for ``nbgrader db assignment add``\n",
    "\n",
    "    :doc:`/command_line_tools/nbgrader-db-assignment-import`\n",
    "        Command line options for ``nbgrader db assignment import``\n",
    "\n",
    "    :doc:`/command_line_tools/nbgrader-db-assignment-remove`\n",
    "        Command line options for ``nbgrader db assignment remove``\n",
    "\n",
    "    :doc:`/command_line_tools/nbgrader-db-assignment-list`\n",
    "        Command line options for ``nbgrader db assignment list``\n",
    "\n",
    "    :doc:`philosophy`\n",
    "        More details on how the nbgrader hierarchy is structured.\n",
    "\n",
    "    :doc:`/configuration/config_options`\n",
    "        Details on ``nbgrader_config.py``"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Most of the important information that nbgrader has access to---information about students, assignments, grades, etc.---is stored in the nbgrader database. Much of this is added to the database automatically by nbgrader, with the exception of two types of information: which students are in your class, and which assignments you have.\n",
    "\n",
    "There are three methods for adding students and assignments to the database. The first is by declaring them explicitly in the `nbgrader_config.py` file, such as:\n",
    "\n",
    "```python\n",
    "c = get_config()\n",
    "c.CourseDirectory.db_assignments = [dict(name=\"ps1\", duedate=\"2015-02-02 17:00:00 UTC\")]\n",
    "c.CourseDirectory.db_students = [\n",
    "    dict(id=\"bitdiddle\", first_name=\"Ben\", last_name=\"Bitdiddle\"),\n",
    "    dict(id=\"hacker\", first_name=\"Alyssa\", last_name=\"Hacker\")\n",
    "]\n",
    "```"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "The second is by writing a Python script and using the :doc:`API </api/index>`. The third way is to use the command line tool ``nbgrader db``, which provides limited command line access to some of the API functionality."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "\n",
    "# remove the existing database, to start fresh\n",
    "rm gradebook.db"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Managing assignments"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To add assignments, we can use the `nbgrader db assignment add` command, which takes the name of the assignment as well as optional arguments (such as its due date):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[DbAssignmentAddApp | INFO] Creating/updating assignment with ID 'ps1': {'duedate': '2015-02-02 17:00:00 UTC'}\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "\n",
    "nbgrader db assignment add ps1 --duedate=\"2015-02-02 17:00:00 UTC\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After we have added the assignment, we can view what assignments exist in the database with `nbgrader db assignment list`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "There are 1 assignments in the database:\n",
      "ps1 (due: 2015-02-02 17:00:00)\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "\n",
    "nbgrader db assignment list"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "An alternate way to add assignments is a batch method of importing a CSV file. The file must have a column called `name`, and may optionally have columns for other assignment properties (such as the due date):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing assignments.csv\n"
     ]
    }
   ],
   "source": [
    "%%file assignments.csv\n",
    "name,duedate\n",
    "ps1,2015-02-02 17:00:00 UTC\n",
    "ps2,2015-02-09 17:00:00 UTC"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then, to import this file, we use the `nbgrader db assignment import` command:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[DbAssignmentImportApp | INFO] Importing from: 'assignments.csv'\n",
      "[DbAssignmentImportApp | INFO] Creating/updating Assignment with name 'ps1': {'duedate': '2015-02-02 17:00:00 UTC'}\n",
      "[DbAssignmentImportApp | INFO] Creating/updating Assignment with name 'ps2': {'duedate': '2015-02-09 17:00:00 UTC'}\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "\n",
    "nbgrader db assignment import assignments.csv"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also remove assignments from the database with `nbgrader db assignment remove`. **Be very careful using this command, as it is possible you could lose data!**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[DbAssignmentRemoveApp | INFO] Removing assignment with ID 'ps1'\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "\n",
    "nbgrader db assignment remove ps1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Managing students"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Managing students in the database works almost exactly the same as managing assignments. To add students, we use the `nbgrader db student add` command:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[DbStudentAddApp | INFO] Creating/updating student with ID 'bitdiddle': {'last_name': 'Bitdiddle', 'first_name': 'Ben', 'email': None}\n",
      "[DbStudentAddApp | INFO] Creating/updating student with ID 'hacker': {'last_name': 'Hacker', 'first_name': 'Alyssa', 'email': None}\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "\n",
    "nbgrader db student add bitdiddle --last-name=Bitdiddle --first-name=Ben\n",
    "nbgrader db student add hacker --last-name=Hacker --first-name=Alyssa"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And to list the students in the database, we use the `nbgrader db student list` command:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "There are 2 students in the database:\n",
      "bitdiddle (Bitdiddle, Ben) -- None\n",
      "hacker (Hacker, Alyssa) -- None\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "\n",
    "nbgrader db student list"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Like with the assignments, we can also batch add students to the database using the `nbgrader db student import` command. We first have to create a CSV file, which is required to have a column for `id`, and optionally may have columns for other student information (such as their name):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing students.csv\n"
     ]
    }
   ],
   "source": [
    "%%file students.csv\n",
    "id,last_name,first_name,email\n",
    "bitdiddle,Bitdiddle,Ben,\n",
    "hacker,Hacker,Alyssa,"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[DbStudentImportApp | INFO] Importing from: 'students.csv'\n",
      "[DbStudentImportApp | INFO] Creating/updating Student with id 'bitdiddle': {'last_name': 'Bitdiddle', 'first_name': 'Ben', 'email': None}\n",
      "[DbStudentImportApp | INFO] Creating/updating Student with id 'hacker': {'last_name': 'Hacker', 'first_name': 'Alyssa', 'email': None}\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "\n",
    "nbgrader db student import students.csv"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also remove students from the database with `nbgrader db student remove`. **Be very careful using this command, as it is possible you could lose data!**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[DbStudentRemoveApp | INFO] Removing student with ID 'bitdiddle'\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "\n",
    "nbgrader db student remove bitdiddle"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python",
   "language": "python",
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
